//
//  CLGAVPlayerViewController.m
//  CLGPlayerDemo
//
//  Created by GuochengLiu on 2016/11/28.
//  Copyright © 2016年 sumavision. All rights reserved.
//

#import "CLGAVPlayerViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#import <SVProgressHUD.h>

@interface CLGAVPlayerViewController ()

@property (weak, nonatomic) IBOutlet UILabel *durationLabel;
@property (weak, nonatomic) IBOutlet UILabel *playTimeLabel;
@property (weak, nonatomic) IBOutlet UISlider *progressSilder;
@property (weak, nonatomic) IBOutlet UIProgressView *bufferedProgressView;
@property (weak, nonatomic) IBOutlet UIButton *playButton;
@property (weak, nonatomic) IBOutlet UILabel *hudLabel;

@property (strong, nonatomic) MPVolumeView *airPlayButton;

@property (assign, nonatomic) BOOL isDragging;



@end

@implementation CLGAVPlayerViewController
{
    id _timeObserver;
}

- (instancetype)initWithMediaURL:(NSURL *)mediaURL
{
    self = [super initWithNibName:@"CLGAVPlayerViewController" bundle:nil];
    
    if (self) {
        self.mediaURL = mediaURL;
        self.autoPlay = YES;
        
        self.asset = [AVAsset assetWithURL:_mediaURL];
        self.playerItem = [AVPlayerItem playerItemWithAsset:_asset];
        self.player = [AVPlayer playerWithPlayerItem:_playerItem];
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.playbackView.player = _player;
    if (_autoPlay == YES) {
        [_player play];
    }
    
    {
        // initial setup
        [_progressSilder setContinuous:NO];
        _isDragging = NO;
        [self.playButton setEnabled:NO];
    }
    
    {
        // Background Play via AirPlay
        NSError *setCategoryError = nil;
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
        
        // Register Control Center
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
        
        MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
        rcc.playCommand.enabled = YES;
        
        [rcc.playCommand addTarget:self action:@selector(play)];
        [rcc.pauseCommand addTarget:self action:@selector(pause)];
        
        [self becomeFirstResponder];
    }
    
    {
        _airPlayButton = [[MPVolumeView alloc] init];
        [_airPlayButton setShowsRouteButton:YES];
        [_airPlayButton setShowsVolumeSlider:NO];
        [self.view addSubview:_airPlayButton];
    }
    
    [self installKVO];
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];
    
    CGFloat width = self.view.frame.size.width;
    CGFloat height = self.view.frame.size.height;
    
    _airPlayButton.frame = CGRectMake(width - 20 - 16, 20 + 16, 20, 20);
    
}
- (void)installKVO
{
    [self.playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
    
    [self.asset addObserver:self forKeyPath:@"duration" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
    
    [self.playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
    
    [self.player addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
    
    [self.player addObserver:self forKeyPath:@"externalPlaybackActive" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:nil];
    
    __weak __typeof__(self) weakSelf = self;
    _timeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        
        
        
        CMTime playTime = weakSelf.player.currentTime;
        CMTime duration = weakSelf.asset.duration;
        weakSelf.playTimeLabel.text = [weakSelf getTimeText:playTime];
        
        
        if (weakSelf.isDragging == NO) {
            [weakSelf.progressSilder setValue:CMTimeGetSeconds(playTime)/CMTimeGetSeconds(duration) animated:YES];
        }
    }];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playItemDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

- (void)playItemDidEnd:(NSNotification *)noti
{
    [self stop];
}

- (void)uninstallKVO
{
    [self.playerItem removeObserver:self forKeyPath:@"status"];
    [self.asset removeObserver:self forKeyPath:@"duration"];
    [self.player removeTimeObserver:_timeObserver];
    [self.player removeObserver:self forKeyPath:@"rate"];
    [self.player removeObserver:self forKeyPath:@"externalPlaybackActive"];
    [self.playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"status"] && [object isKindOfClass:[AVPlayerItem class]]) {
        AVPlayerItem *playerItem = (AVPlayerItem *)object;
        NSLog(@"status %li", (long)playerItem.status);
        
        if (playerItem.status == AVPlayerItemStatusFailed) {
            [SVProgressHUD showErrorWithStatus:@"该视频无法播放"];
        } else if (playerItem.status == AVPlayerItemStatusReadyToPlay) {
            [self.progressSilder setEnabled:YES];
            [self.playButton setEnabled:YES];
        }
    }
    
    if ([keyPath isEqualToString:@"duration"] && [object isKindOfClass:[AVAsset class]]) {
        AVAsset *asset = (AVAsset *)object;
        
        CMTime duration = asset.duration;
        [self.durationLabel setText:[self getTimeText:duration]];
    }
    
    if ([keyPath isEqualToString:@"loadedTimeRanges"] && [object isKindOfClass:[AVPlayerItem class]]) {
        AVPlayerItem *playerItem = (AVPlayerItem *)object;
        
        NSArray *loadedTimeRanges = [playerItem loadedTimeRanges];
        CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];
        
        float bufferedDuration = CMTimeGetSeconds(timeRange.start) + CMTimeGetSeconds(timeRange.duration);
        
        CMTime duration = playerItem.asset.duration;
        
        float progress = bufferedDuration/CMTimeGetSeconds(duration);
        if (progress <= 1) {
            [_bufferedProgressView setProgress:progress animated:YES];
        }
    }
    
    if ([keyPath isEqualToString:@"rate"] && [object isKindOfClass:[AVPlayer class]]) {
        AVPlayer *player = (AVPlayer *)object;
        float rate = player.rate;
        if (rate > 0) {
            [self.playButton setSelected:YES];
        } else {
            [self.playButton setSelected:NO];
        }
    }
    
    if ([keyPath isEqualToString:@"externalPlaybackActive"] && [object isKindOfClass:[AVPlayer class]]) {
        AVPlayer *player = (AVPlayer *)object;
        BOOL active = player.isExternalPlaybackActive;

        if (active) {
            [_hudLabel setText:@"正在通过Airplay播放"];
            [_hudLabel setHidden:NO];
        } else {
            [_hudLabel setText:@""];
            [_hudLabel setHidden:YES];
            [_player play];
        }
    }
    
}

- (NSString *)getTimeText:(CMTime)time
{
    NSUInteger tTotalSeconds = CMTimeGetSeconds(time);
    
    NSUInteger tHours = floor(tTotalSeconds / 3600);
    NSUInteger tMinutes = floor(tTotalSeconds % 3600 / 60);
    NSUInteger tSeconds = floor(tTotalSeconds % 3600 % 60);
    NSString *timeText;
    if (tHours == 0) {
        timeText = [NSString stringWithFormat:@"%02lu:%02lu", (unsigned long)tMinutes, (unsigned long)tSeconds];
    } else {
        timeText = [NSString stringWithFormat:@"%lu:%02lu:%02lu",(unsigned long)tHours, (unsigned long)tMinutes, (unsigned long)tSeconds];
    }
    
    return timeText;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

- (IBAction)onHitBackButton:(UIButton *)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)progressSliderDidChange:(UISlider *)sender {
    
    float value = sender.value;
    
    float seconds = value * CMTimeGetSeconds(_asset.duration);
    
    CMTime seekTime = CMTimeMake(seconds, 1);
    
    [_player seekToTime:seekTime];
    
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        _isDragging = NO;
    });
}

- (IBAction)beginDragging:(UISlider *)sender {
    _isDragging = YES;
}

- (IBAction)onHitPlayButton:(UIButton *)sender {
    if (sender.isSelected) {
        [self.player pause];
    } else {
        [self.player play];
    }
}

- (void)play
{
    [_player play];
}

- (void)pause
{
    [_player pause];
}

- (void)stop
{
    [_player seekToTime:CMTimeMake(0, 1)];
    [_player pause];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
}

- (void)dealloc
{
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
    [self uninstallKVO];
    NSLog(@"[%@] dealloc", [self class]);
}


- (BOOL)canBecomeFirstResponder
{
    return YES;
}


@end
